js的继承有哪些方式?

来源:博客站 01月25日 12:27

在JavaScript中,实现继承有多种方式。这些方式随着ECMAScript标准的演进而逐渐改进和标准化。以下是几种常见的继承方式:

  1. 原型链继承(Prototypal Inheritance): 虽然这不是传统意义上的“类继承”,但它是JavaScript早期实现继承的一种方式。通过将一个对象的原型设置为另一个对象,从而实现继承。

    function Parent() {
        this.property = 'parent';
    }
    
    Parent.prototype.getParentProperty = function() {
        return this.property;
    };
    
    function Child() {
        Parent.call(this); // 借用构造函数继承属性
        this.property = 'child';
    }
    
    Child.prototype = new Parent(); // 原型链继承方法
    Child.prototype.constructor = Child; // 修正constructor指向
    
    var child = new Child();
    console.log(child.getParentProperty()); // 输出 'parent'(通过原型链继承的方法)
    console.log(child.property); // 输出 'child'(自己的属性)
    
  2. 借用构造函数继承(Constructor Stealing/Borrowing): 也称为“经典继承”或“伪类继承”。通过在子类的构造函数中调用父类的构造函数,实现父类属性的继承。但这种方法无法继承父类原型上的方法。

    function Parent(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    
    function Child(name, age) {
        Parent.call(this, name); // 借用Parent构造函数
        this.age = age;
    }
    
    var child = new Child('John', 18);
    console.log(child.name); // 输出 'John'
    console.log(child.age); // 输出 18
    console.log(child.colors); // 输出 ['red', 'blue', 'green']
    
  3. 组合继承(Combination Inheritance): 结合了原型链继承和借用构造函数继承的优点,既继承了父类的实例属性,又继承了父类原型上的方法。这是JavaScript中最常用的继承模式。

    function Parent(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    
    Parent.prototype.getName = function() {
        return this.name;
    };
    
    function Child(name, age) {
        Parent.call(this, name); // 借用构造函数继承属性
        this.age = age;
    }
    
    Child.prototype = new Parent(); // 原型链继承方法
    Child.prototype.constructor = Child; // 修正constructor指向
    Child.prototype.getAge = function() {
        return this.age;
    };
    
    var child = new Child('John', 18);
    console.log(child.getName()); // 输出 'John'
    console.log(child.getAge()); // 输出 18
    console.log(child.colors); // 输出 ['red', 'blue', 'green']
    
  4. 原型式继承(Prototypal Inheritance with Object.create): 使用Object.create方法创建对象,并指定其原型。这是ES5引入的方法,可以更方便地实现原型链继承。

    var parent = {
        name: 'parent',
        colors: ['red', 'blue', 'green']
    };
    
    var child = Object.create(parent);
    child.name = 'child';
    child.age = 18;
    
    console.log(child.name); // 输出 'child'
    console.log(child.colors); // 输出 ['red', 'blue', 'green'](共享引用)
    
  5. 寄生组合式继承(Parasitic Combination Inheritance): 这是组合继承的优化版本,通过借用构造函数来继承属性,并使用寄生式继承来继承父类原型上的方法,避免了组合继承中父类实例的重复创建。

    function Parent(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }
    
    Parent.prototype.getName = function() {
        return this.name;
    };
    
    function Child(name, age) {
        Parent.call(this, name); // 借用构造函数继承属性
        this.age = age;
    }
    
    Child.prototype = Object.create(Parent.prototype); // 寄生式继承原型
    Child.prototype.constructor = Child; // 修正constructor指向
    Child.prototype.getAge = function() {
        return this.age;
    };
    
    var child = new Child('John', 18);
    console.log(child.getName()); // 输出 'John'
    console.log(child.getAge()); // 输出 18
    console.log(child.colors); // 输出 ['red', 'blue', 'green']
    
  6. 类继承(Class Inheritance): ES6引入了class语法,使得继承更加直观和易读。class语法在内部实际上是基于原型链实现的。

    class Parent {
        constructor(name) {
            this.name = name;
            this.colors = ['red', 'blue', 'green'];
        }
    
        getName() {
            return this.name;
        }
    }
    
    class Child extends Parent {
        constructor(name, age) {
            super(name); // 调用父类的构造函数
            this.age = age;
        }
    
        getAge() {
            return this.age;
        }
    }
    
    const child = new Child('John', 18);
    console.log(child.getName()); // 输出 'John'
    console.log(child.getAge()); // 输出 18
    console.log(child.colors); // 输出 ['red', 'blue', 'green']
    

每种方式都有其优点和缺点,开发者可以根据具体的需求选择合适的继承方式。

原文出处: 内容源于AI仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/336.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。

今日推荐

HTTP状态码详解
webpack有哪些常见的Loader
uni-app中的nvue是什么?它有什么优势?
UniApp 的优势有哪些?
C盘空间告急?手把手教你安全清理,告别卡顿!
从开机到激活:新电脑Windows系统激活全攻略
开源软件为何会成为“兵家必争之地”?
如何创建自己的小程序,需要注意哪些